home *** CD-ROM | disk | FTP | other *** search
- /* NEWFLATS.C replace and/or add flats to an IWAD file */
- /* Stefan Gustavson 1994 */
-
- #include <stdio.h>
-
- typedef struct
- {
- char name[8];
- long pos, size;
- } direntry;
-
- int getshort(filep)
- FILE *filep;
- {
- short s;
- s = getc(filep) & 0xff;
- s += (getc(filep) & 0xff)<<8;
- return(s);
- }
-
- int getlong(filep)
- FILE *filep;
- {
- int l;
- l = getc(filep) & 0xff;
- l += (getc(filep) & 0xff) <<8;
- l += (getc(filep) & 0xff) <<16;
- l += (getc(filep) & 0xff) <<24;
- return(l);
- }
-
- void putshort(d, filep)
- short d;
- FILE *filep;
- {
- putc(d & 0xff, filep);
- putc((d & 0xff00) >> 8, filep);
- }
-
- void putlong(d, filep)
- long d;
- FILE *filep;
- {
- putc(d & 0xff, filep);
- putc((d & 0xff00) >> 8, filep);
- putc((d & 0xff0000) >> 16, filep);
- putc((d & 0xff000000) >> 24, filep);
- }
-
-
- int readdir(dir, wadfile)
- direntry dir[];
- FILE *wadfile;
- {
- int i, numentries, dirstart;
- fseek(wadfile, 4, 0); /* Skip four bytes */
- numentries = getlong(wadfile);
- dirstart = getlong(wadfile);
- if(fseek(wadfile, dirstart, 0))
- {
- fprintf(stderr, "File seek error.\n");
- exit(-1);
- }
- for(i=0; i<numentries; i++)
- {
- dir[i].pos = getlong(wadfile);
- dir[i].size = getlong(wadfile);
- fread(dir[i].name, 8, 1, wadfile);
- }
- return numentries;
- }
-
-
- void copytoflats(iwadfile, dir1, numentries1,
- newiwadfile, dir3, numentries3)
- FILE *iwadfile;
- direntry dir1[];
- int numentries1;
- FILE *newiwadfile;
- direntry dir3[];
- int *numentries3;
- {
- int i, j, pos;
- fprintf(newiwadfile, "IWAD");
- putlong(0, newiwadfile); /* Save for later */
- putlong(0, newiwadfile); /* Save for later */
- pos = 12;
- i = 0;
- while(strncmp(dir1[i].name, "F_START", 7))
- {
- fseek(iwadfile, dir1[i].pos, 0);
- for(j=0; j<dir1[i].size; j++)
- putc(getc(iwadfile), newiwadfile);
- dir3[i].pos = pos;
- dir3[i].size = dir1[i].size;
- pos += dir3[i].size;
- strncpy(dir3[i].name, dir1[i].name, 8);
- i++;
- }
- *numentries3 = i;
- }
-
-
- void mergeflats(iwadfile, dir1, numentries1,
- pwadfile, dir2, numentries2,
- newiwadfile, dir3, numentries3)
- FILE *iwadfile;
- direntry dir1[];
- int numentries1;
- FILE *pwadfile;
- direntry dir2[];
- int numentries2;
- FILE *newiwadfile;
- direntry dir3[];
- int *numentries3;
- {
- int i1, i2, j, pos;
- i1 = 0;
- i2 = 0;
- while(strcmp(dir1[i1].name, "F_START")) i1++;
- while(strcmp(dir2[i2].name, "F_START")) i2++;
-
- /* Find out where the flats section starts in the NEW file. */
- /* Note that this will not necessarily be the same position */
- /* as in the original IWAD. There are holes in DOOM.WAD ! */
- /* Also, don't trust the position of zero length entries. */
- for(j=0; ((*numentries3-j)>=0) & (dir3[*numentries3-j].size == 0); j++);
- if((*numentries3-j)<0)
- pos = 12; /* The flats start directly after the header */
- else
- /* The flats start after the closest preceding non-zero length entry */
- pos = dir3[*numentries3-j].pos + dir3[*numentries3-j].size;
-
- while(strcmp(dir1[i1].name, "F1_END") & strcmp(dir2[i2].name, "F1_END"))
- {
- if(strncmp(dir1[i1].name, dir2[i2].name, 8))
- {
- /* No replacement - copy the old entry */
- fseek(iwadfile, dir1[i1].pos, 0);
- for(j=0; j<dir1[i1].size; j++)
- putc(getc(iwadfile), newiwadfile);
- dir3[*numentries3].pos = pos;
- dir3[*numentries3].size = dir1[i1].size;
- pos += dir3[*numentries3].size;
- strncpy(dir3[*numentries3].name, dir1[i1].name, 8);
- (*numentries3)++;
- i1++;
- }
- else
- /* Replacement entry - copy the new entry instead */
- {
- fseek(pwadfile, dir2[i2].pos, 0);
- for(j=0; j<dir2[i2].size; j++)
- putc(getc(pwadfile), newiwadfile);
- dir3[*numentries3].pos = pos;
- dir3[*numentries3].size = dir2[i2].size;
- pos += dir3[*numentries3].size;
- strncpy(dir3[*numentries3].name, dir2[i2].name, 8);
- (*numentries3)++;
- i1++;
- i2++;
- }
- }
- /* Copy any remaining original entries */
- while(strcmp(dir1[i1].name, "F1_END"))
- {
- fseek(iwadfile, dir1[i1].pos, 0);
- for(j=0; j<dir1[i1].size; j++)
- putc(getc(iwadfile), newiwadfile);
- dir3[*numentries3].pos = pos;
- dir3[*numentries3].size = dir1[i1].size;
- pos += dir3[*numentries3].size;
- strncpy(dir3[*numentries3].name, dir1[i1].name, 8);
- (*numentries3)++;
- i1++;
- }
- /* Add new entries, if any */
- while(strcmp(dir2[i2].name, "F1_END"))
- {
- fseek(pwadfile, dir2[i2].pos, 0);
- for(j=0; j<dir2[i2].size; j++)
- putc(getc(pwadfile), newiwadfile);
- dir3[*numentries3].pos = pos;
- dir3[*numentries3].size = dir2[i2].size;
- pos += dir3[*numentries3].size;
- strncpy(dir3[*numentries3].name, dir2[i2].name, 8);
- (*numentries3)++;
- i2++;
- }
-
- /* Repeat the above procedure for the F2 section as well */
-
- while(strcmp(dir1[i1].name, "F2_END") & strcmp(dir2[i2].name, "F2_END"))
- {
- if(strncmp(dir1[i1].name, dir2[i2].name, 8))
- {
- /* No replacement - copy the old entry */
- fseek(iwadfile, dir1[i1].pos, 0);
- for(j=0; j<dir1[i1].size; j++)
- putc(getc(iwadfile), newiwadfile);
- dir3[*numentries3].pos = pos;
- dir3[*numentries3].size = dir1[i1].size;
- pos += dir3[*numentries3].size;
- strncpy(dir3[*numentries3].name, dir1[i1].name, 8);
- (*numentries3)++;
- i1++;
- }
- else
- /* Replacement entry - copy the new entry instead */
- {
- fseek(pwadfile, dir2[i2].pos, 0);
- for(j=0; j<dir2[i2].size; j++)
- putc(getc(pwadfile), newiwadfile);
- dir3[*numentries3].pos = pos;
- dir3[*numentries3].size = dir2[i2].size;
- pos += dir3[*numentries3].size;
- strncpy(dir3[*numentries3].name, dir2[i2].name, 8);
- (*numentries3)++;
- i1++;
- i2++;
- }
- }
- /* Copy any remaining original entries */
- while(strcmp(dir1[i1].name, "F2_END"))
- {
- fseek(iwadfile, dir1[i1].pos, 0);
- for(j=0; j<dir1[i1].size; j++)
- putc(getc(iwadfile), newiwadfile);
- dir3[*numentries3].pos = pos;
- dir3[*numentries3].size = dir1[i1].size;
- pos += dir3[*numentries3].size;
- strncpy(dir3[*numentries3].name, dir1[i1].name, 8);
- (*numentries3)++;
- i1++;
- }
- /* Add new entries, if any */
- while(strcmp(dir2[i2].name, "F2_END"))
- {
- fseek(pwadfile, dir2[i2].pos, 0);
- for(j=0; j<dir2[i2].size; j++)
- putc(getc(pwadfile), newiwadfile);
- dir3[*numentries3].pos = pos;
- dir3[*numentries3].size = dir2[i2].size;
- pos += dir3[*numentries3].size;
- strncpy(dir3[*numentries3].name, dir2[i2].name, 8);
- (*numentries3)++;
- i2++;
- }
- /* Write the F2_END and F_END markers and exit */
- dir3[*numentries3].pos = pos;
- dir3[*numentries3].size = 0;
- strncpy(dir3[*numentries3].name, "F2_END", 8);
- (*numentries3)++;
- dir3[*numentries3].pos = pos;
- dir3[*numentries3].size = 0;
- strncpy(dir3[*numentries3].name, "F_END", 8);
- (*numentries3)++;
- }
-
-
- void writedir(wadfile, dir, n)
- FILE *wadfile;
- direntry dir[];
- int n;
- {
- int i, dirstart;
-
- for(i=0; i<n; i++)
- {
- putlong(dir[i].pos, wadfile);
- putlong(dir[i].size, wadfile);
- fwrite(dir[i].name, 8, 1, wadfile);
- }
- for(i=0; ((n-i)>=0) & (dir[n-i].size == 0); i++);
- if((n-i)<0)
- dirstart = 12;
- else
- dirstart = dir[n-i].pos + dir[n-i].size;
-
- fseek(wadfile, 4, 0);
- putlong(n, wadfile);
- putlong(dirstart, wadfile);
- }
-
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- FILE *iwadfile, *pwadfile, *newiwadfile;
- char identifier[4];
- int i, numentries1, numentries2, numentries3;
- direntry dir1[4096], dir2[1024], dir3[4096];
-
- if (argc != 4)
- {
- fprintf(stderr, "Usage: %s iwad pwad newiwad\n", argv[0]);
- exit(-1);
- }
- iwadfile = fopen(argv[1], "r");
- if(iwadfile == NULL)
- {
- fprintf(stderr, "File %s not found.\n", argv[1]);
- exit(-1);
- }
- fread(identifier, 4, 1, iwadfile);
- if(strncmp("IWAD", identifier, 4))
- {
- fprintf(stderr, "File %s is not an IWAD file.\n", argv[1]);
- exit(-1);
- }
- numentries1 = readdir(dir1, iwadfile);
-
- pwadfile = fopen(argv[2], "r");
- if(pwadfile == NULL)
- {
- fprintf(stderr, "File %s not found.\n", argv[2]);
- exit(-1);
- }
- fread(identifier, 4, 1, pwadfile);
- if(strncmp("PWAD", identifier, 4))
- {
- fprintf(stderr, "File %s is not a PWAD file.\n", argv[2]);
- exit(-1);
- }
- numentries2 = readdir(dir2, pwadfile);
- newiwadfile = fopen(argv[3], "w");
- if(pwadfile == NULL)
- {
- fprintf(stderr, "Unable to open output file %s.\n", argv[3]);
- exit(-1);
- }
- printf("Copying other entries from %s to %s...\n", argv[1], argv[3]);
- copytoflats(iwadfile, dir1, numentries1,
- newiwadfile, dir3, &numentries3);
- printf("Merging flat entries from %s and %s into %s...\n",
- argv[1], argv[2], argv[3]);
- mergeflats(iwadfile, dir1, numentries1,
- pwadfile, dir2, numentries2,
- newiwadfile, dir3, &numentries3);
- printf("Writing directory to %s.\n", argv[3]);
- writedir(newiwadfile, dir3, numentries3);
-
- fclose(iwadfile);
- fclose(pwadfile);
- fclose(newiwadfile);
- }
-
-
-
-